package demo.hdz.mediacodecdecode.customview;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.SurfaceTexture;
import android.os.Build;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;

import java.lang.ref.WeakReference;

import demo.hdz.mediacodecdecode.Logger;
import demo.hdz.mediacodecdecode.Util;
import demo.hdz.mediacodecdecode.interfaces.IDecodeManager;
import demo.hdz.mediacodecdecode.interfaces.IDecodeOperate;

/**
 * @author hdz
 * @date 2019/04/12
 */
public class VideoTextureView extends TextureView implements TextureView.SurfaceTextureListener, IVideoView {

    private static final String TAG = "VideoTextureView";
    public static SurfaceTexture mSurfaceTexture = null;
    private static int mScreenWidth, mScreenHeight, mVideoWidth, mVideoHeight;
    private IDecodeOperate mDecodeOperate = null;
    private WeakReference<Context> mWeakContext = null;
    private VideoViewUtil mVideoViewUtil;

    public VideoTextureView(Context context) {
        super(context);
        Logger.d(TAG + ",VideoTextureView: A");
        init(context);
    }

    public VideoTextureView(Context context, AttributeSet attrs) {
        super(context, attrs);
        Logger.d(TAG + ",VideoTextureView: B");
        init(context);
    }

    public VideoTextureView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        Logger.d(TAG + ",VideoTextureView: C");
        init(context);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public VideoTextureView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        Logger.d(TAG + ",VideoTextureView: D");
        setSurfaceTextureListener(this);
    }

    public static void setSize(int screenWidth, int screenHeight, int videoWidth, int videoHeight) {
        Logger.d(TAG + ",setSize: " + screenWidth + "x" + screenHeight + " " + videoWidth + "x" + videoHeight);
        mScreenWidth = screenWidth;
        mScreenHeight = screenHeight;
        mVideoWidth = videoWidth;
        mVideoHeight = videoHeight;
    }

    private void init(Context context) {
        mVideoViewUtil = new VideoViewUtil();
        setSurfaceTextureListener(this);
        mWeakContext = new WeakReference<>(context);
    }

    @Override
    protected void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
            if (mScreenWidth < mScreenHeight) {
                int tmp = mScreenWidth;
                mScreenWidth = mScreenHeight;
                mScreenHeight = tmp;
            }
        } else {
            if (mScreenWidth > mScreenHeight) {
                int tmp = mScreenWidth;
                mScreenWidth = mScreenHeight;
                mScreenHeight = tmp;
            }
        }
        mVideoViewUtil.adjustSize(this, mScreenWidth, mScreenHeight, mVideoWidth, mVideoHeight);
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mScreenWidth = w;
        mScreenHeight = h;
        mVideoViewUtil.adjustSize(this, mScreenWidth, mScreenHeight, mVideoWidth, mVideoHeight);
        Logger.d(TAG + ",onSizeChanged: " + w + "x" + h + ", " + oldw + "x" + oldh);
    }

    @Override
    protected void onVisibilityChanged(View changedView, int visibility) {
        super.onVisibilityChanged(changedView, visibility);
        //mVideoViewUtil.adjustSize(this, mScreenWidth, mScreenHeight, mVideoWidth, mVideoHeight);
        Logger.d(TAG + ",onVisibilityChanged: " + Util.visibility2String(visibility));
    }

    @Override
    protected void onWindowVisibilityChanged(int visibility) {
        super.onWindowVisibilityChanged(visibility);
        Logger.d(TAG + ",onWindowVisibilityChanged: " + Util.visibility2String(visibility));
    }

    @Override
    public boolean isAvailable() {
        Logger.d(TAG + ",isAvailable: " + mSurfaceTexture);
        return mSurfaceTexture != null;
    }


    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
        Logger.d(TAG + ",onSurfaceTextureAvailable: " + width + " " + height);
        if (mSurfaceTexture != null) {
            this.setSurfaceTexture(mSurfaceTexture);
        } else {
            mSurfaceTexture = surface;
        }
        mScreenWidth = width;
        mScreenHeight = height;
        mVideoViewUtil.adjustSize(this, mScreenWidth, mScreenHeight, mVideoWidth, mVideoHeight);
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
        mSurfaceTexture = surface;
        Logger.d(TAG + ",onSurfaceTextureSizeChanged: " + width + "x" + height);
        mScreenWidth = width;
        mScreenHeight = height;
        mVideoViewUtil.adjustSize(this, mScreenWidth, mScreenHeight, mVideoWidth, mVideoHeight);
    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        mSurfaceTexture = surface;
        Logger.d(TAG + ",onSurfaceTextureDestroyed: " + surface);
        return false;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
        //mSurfaceTexture = surface;
        //Logger.d(TAG+",onSurfaceTextureUpdated: " + surface);
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Logger.d(TAG + ",onTouchEvent: " + event.toString());
        float x = event.getRawX();
        if (event.getAction() == MotionEvent.ACTION_UP) {
            if (x > mScreenWidth / 2) {
                Logger.d(TAG + ",onTouchEvent: 暂停");
                startOrPause(true);
            } else {
                Logger.d(TAG + ",onTouchEvent: 开始");
                startOrPause(false);
            }
        }
        return true;
    }

    @Override
    public Surface getSurface() {
        if (mSurfaceTexture != null) {
            return new Surface(mSurfaceTexture);
        }
        return null;
    }

    @Override
    public void setListener(IDecodeOperate o) {
        mDecodeOperate = o;
    }

    @Override
    public void startOrPause(boolean pause) {
        if (mDecodeOperate != null) {
            mDecodeOperate.startOrPause(pause);
        }
    }

    @Override
    public void stop() {
        if (mDecodeOperate != null) {
            mDecodeOperate.stop();
        }
    }
}
